package com.xiu.travel.security.service.impl;

import com.xiu.travel.util.MinioClientUtil;
import com.xiu.travel.util.PicUtils;
import com.xiu.travel.util.api.CommonResult;
import com.xiu.travel.util.api.ResultCode;
import com.xiu.travel.domain.ResPathColorDO;
import com.xiu.travel.security.FileService;
import io.swagger.v3.oas.annotations.Parameter;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletResponse;
import jakarta.validation.constraints.NotNull;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.*;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@Service
@Slf4j
public class FileServiceImpl implements FileService
{
    @Autowired
    Environment environment;
    @Autowired
    MinioClientUtil minioClientUtil;

    @Value("${minio.endpoint}")
    private String ENDPOINT;

    /**
     * 文件上传服务
     *
     * @param file 文件
     * @return R<String> 图片路径
     */
    @Override
    public CommonResult<ResPathColorDO> upFile(@Parameter(name = "文件") @NotNull MultipartFile file) throws Exception
    {

        if (file.isEmpty())
        {
            return CommonResult.failed("未选择需上传的文件");
        }

        String
                md5Name =
                DigestUtils.md5DigestAsHex((file.getOriginalFilename() +
                        "qianlanyuyun0.02333").getBytes(StandardCharsets.UTF_8));
        String fileSuffix = Objects.requireNonNull(file.getOriginalFilename())
                .substring(file.getOriginalFilename().lastIndexOf("."));
        String filePath = new File("src/main/resources/upload/"
                + Objects.requireNonNull(file.getOriginalFilename())
                .substring(file.getOriginalFilename().lastIndexOf(".") + 1)).getAbsolutePath();
        String srcFilePath = "";

        File fileUpload = new File(filePath);

        if (!fileUpload.exists())
        {
            System.out.println(fileUpload.mkdirs());
        }
        fileUpload = new File(filePath, md5Name + fileSuffix);
        srcFilePath = fileUpload.getAbsolutePath();
        if (fileUpload.exists())
        {
            return CommonResult.failed("上传的文件已存在");
        }
        try
        {
            file.transferTo(fileUpload);
        }
        catch (IOException e)
        {
            CommonResult.failed("上传文件到服务器失败");
        }

//        文件压缩
        String resPath = "";
        resPath = ENDPOINT + "/xiu/img/" + "m_" + md5Name + fileSuffix;


        if (Objects.requireNonNull(file.getContentType())
                .contains("image/") && !Objects.requireNonNull(file.getContentType()).contains("image/heic"))
        {
            String
                    picRes =
                    PicUtils.compressPicForScale(srcFilePath, filePath +
                            "/" +
                            "m_" +
                            md5Name +
                            fileSuffix, 15, 0.66, 4000, 4000);
            log.info("picRes:{}", picRes);
        }
        minioClientUtil.uploadFile("xiu", "/img/" +
                "m_" +
                md5Name +
                fileSuffix, new FileInputStream(srcFilePath), file.getSize());

        return CommonResult.success(
                new ResPathColorDO(resPath, PicUtils.getMedianColor2String(srcFilePath)));

    }

    /**
     * 多个文件上传服务
     *
     * @param request 多个文件
     * @return 路径数组
     */
    @Override
    public CommonResult<List<ResPathColorDO>> upFiles(@Parameter(name = "文件", required = true) HttpServletRequest request) throws
            Exception
    {
        List<ResPathColorDO> paths = new ArrayList<>();
        List<MultipartFile> files = ((MultipartHttpServletRequest) request).getFiles("file");
        for (MultipartFile f : files)
        {
            paths.add(upFile(f).getData());
        }
        return CommonResult.success(paths);
    }

    /**
     * 文件下载服务
     *
     * @param name     文件名
     * @param response HttpServletResponse
     */
    @SneakyThrows
    @Override
    public void downloadFile(String name, HttpServletResponse response)
    {
        System.out.println("/Users/yingyingying/poject/mate/aitodo-cloud/xiu-travel-open/src/main/resources/gen/1/" +
                name +
                "/code.zip");
        File file = new File("src/main/resources/upload/"
                + Objects.requireNonNull(name)
                .substring(name.lastIndexOf(".") + 1));

        if (!file.exists())
        {
            CommonResult.success(ResultCode.UN_FILE, null);
        }
        response.setContentType("application/force-download");
        response.addHeader("Content-Disposition", "attachment;fileName=" +
                URLEncoder.encode(name, StandardCharsets.UTF_8) +
                ".zip");

        byte[] buffer = new byte[1024];

        FileInputStream in = new FileInputStream(file);
        BufferedInputStream bin = new BufferedInputStream(in);

        OutputStream out = response.getOutputStream();
        int i = bin.read(buffer);
        while (i != -1)
        {
            out.write(buffer, 0, i);
            i = bin.read(buffer);
        }
        CommonResult.success("下载成功");
    }

    @Override
    public CommonResult<ResPathColorDO> picUpload(MultipartFile file, String picName) throws Exception
    {
        if (file.isEmpty())
        {
            return CommonResult.failed("未选择需上传的文件");
        }

        String md5Name = Objects.isNull(picName) ?  file.getOriginalFilename() : picName;

        String fileSuffix = Objects.requireNonNull(file.getOriginalFilename())
                .substring(file.getOriginalFilename().lastIndexOf("."));
        String filePath = new File("src/main/resources/upload/"
                + Objects.requireNonNull(file.getOriginalFilename())
                .substring(file.getOriginalFilename().lastIndexOf(".") + 1)).getAbsolutePath();
        String srcFilePath = "";

        File fileUpload = new File(filePath);

        if (!fileUpload.exists())
        {
            System.out.println(fileUpload.mkdirs());
        }
        fileUpload = new File(filePath, md5Name + fileSuffix);
        srcFilePath = fileUpload.getAbsolutePath();
        if (fileUpload.exists())
        {
            return CommonResult.failed("上传的文件已存在");
        }
        try
        {
            file.transferTo(fileUpload);
        }
        catch (IOException e)
        {
            CommonResult.failed("上传文件到服务器失败");
        }

//        文件压缩
        String resPath = "";
        resPath = ENDPOINT + "/xiu/pic/" + "m_" + md5Name + fileSuffix;


        if (Objects.requireNonNull(file.getContentType())
                .contains("image/") && !Objects.requireNonNull(file.getContentType()).contains("image/heic"))
        {
            String
                    picRes =
                    PicUtils.compressPicForScale(srcFilePath, filePath +
                            "/" +
                            "m_" +
                            md5Name +
                            fileSuffix, 15, 0.66, 4000, 4000);
            log.info("picRes:{}", picRes);
        }
        minioClientUtil.uploadFile("xiu", "/pic/" +
                "m_" +
                md5Name +
                fileSuffix, new FileInputStream(srcFilePath), file.getSize());

        return CommonResult.success(
                new ResPathColorDO(resPath, PicUtils.getMedianColor2String(srcFilePath)));
    }

}
